package com.godyao.utils;

import cn.hutool.core.date.DateUtil;
//import com.godyao.entity.UrlMapInfo;
//import com.godyao.repository.UrlMapInfoRepository;
//import org.h2.util.DateTimeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;

/**
 * @author godyao
 * @date 2022/2/27
 */
public class ShortUrlGeneratorIdWorker {


    private static final String DOMAIN = "http://micro/";

    /**
     * 内存缓存的最大值
     */
    private long maxId = 0;

    /**
     * 步长，每次DB获取的长度
     */
    private static final int DELTA = 10;


    /**
     * 长短链接映射容器
     */
    private static final Map<String, String> dbMap = new HashMap<>();

    private Table table = new Table();


    public static void main(String[] args) {
        final ShortUrlGeneratorIdWorker shortUrlGeneratorIdWorker = new ShortUrlGeneratorIdWorker();
        for (int i = 0; i < 100; i++) {
            String s = "http://longLinkDomain/" + i;
            String shortUrl = shortUrlGeneratorIdWorker.generate(s);
            System.out.println("生成短链接：" + shortUrl + ", 获取到原始链接为：" + shortUrlGeneratorIdWorker.get(shortUrl));
        }
    }

    private String get(String shortUrl) {
        return dbMap.get(shortUrl);
    }

    public String generate(String str) {
        if (maxId % DELTA == 0){
            maxId = table.auto();
        }
        long id = maxId --;
        // 转换成62进制的4位短链接
        String s = parseInteger2Char(id, 62, (o) -> {
            if (o <= 9) return (char) ('0' + o);
            if (o >= 10 && o < 36) return (char) ('a' + (o - 10));
            return (char) ('A' + (o - 36));
        });
        String ret = DOMAIN + s;
        // insertTODB
        dbMap.put(ret, str);
        return ret;
    }

    private String parseInteger2Char(Long id, int hex, Function<Long, Character> mapperFunction) {
        // 进制转换
        final Stack<Long> stack = new Stack();
        while (true) {
            long n = id % hex;
            stack.push(n);
            id /= hex;
            if (id < hex) {
                stack.push(id);
                break;
            }
        }
        // 短链接字符串映射
        final StringBuffer stringBuffer = new StringBuffer();
        while (!stack.isEmpty()) {
            stringBuffer.append(mapperFunction.apply(stack.pop()));
        }
        return stringBuffer.toString();
    }

    //private synchronized Long getMaxId() {
    //    return urlMapInfoRepository.findMaxId() + DELTA;
    //}
    /**
     * 模拟DB自增获取操作
     */
    class Table {
        // 原子类，避免并发问题
        private AtomicInteger id = new AtomicInteger(0);

        // 此处统计DB请求次数
        int count = 0;
        public Integer auto() {
            count ++;
            System.out.println("DB请求次数 : " + count);
            return id.getAndAdd(DELTA);
        }
    }

}
